using Gameplay.PVE.Entity;
using Gameplay.PVE.Skill;
using Gameplay.PVE.Utils;
using UnityEngine;
using Yoozoo.Libs;
using Yoozoo.Managers;
using System.Collections.Generic;
using Gameplay.PVE.Config;
using Yoozoo.Framework.Managers;
using Yoozoo.Gta.Common;

namespace Gameplay.PVE
{
    public class BattleComponennt : IComponent,ITransmit
    {
        //战斗组件
        private BattleUnit unit;
        private ElementSystem elementSystem;
        private SkillPassiveTrigger passiveTrigger;
        private List<Vector3> subSkills;
        private Dictionary<int,SkillBase> skills = new Dictionary<int,SkillBase>();
        private SkillBase currentSkill;
        private SkillShootMove moveAttack;
        private SkillShootBase squatAttack;
        private int normalAttackId;
        private int normalSquatAttackId;
        private List<int> rpgNormalAttackList = new List<int>();
        private int initiativeSkillId;
        //private List<AutoSkill> autoSkillList = new List<AutoSkill>();
        private int autoSkillId;

        private float lastCd = 0;

        private bool isFocus = false;

        private int leftAmmoCount;
        private float startReloadTime;

        private int currentNormalAttackIndex;

        private float attackCdStartTime;
        private float attackCd;

        private Dictionary<int,int> addPassiveSkillList = new Dictionary<int,int>();

        //空技能，用于施加元素
        private SkillBase bornSkill;
        //private List<int> removePassiveSkillList = new List<int>();

        void IClass.OnReset()
        {
            isCanSkill = false;
            moveAttack = null;
            squatAttack = null;
            foreach (var item in skills.Values)
            {
                ClassManager.Free(item);
            }
            skills.Clear();
            currentSkill = null;
            addPassiveSkillList.Clear();
            ClassManager.Free(passiveTrigger);
            passiveTrigger = null;
            ClassManager.Free(elementSystem);
            elementSystem = null;
            if (bornSkill != null)
            {
                ClassManager.Free(bornSkill);
            }
            bornSkill = null;
            //removePassiveSkillList.Clear();
            ResidentHandler.Inst.RemoveFunction("pveManager.SetHeroCanSkill");
        }

        void IComponent.OnInitialize(UnitBase unit)
        {
            this.unit = unit as BattleUnit;
            elementSystem = ClassManager.Get<ElementSystem>();
            elementSystem.Initialize();
            passiveTrigger = ClassManager.Get<SkillPassiveTrigger>();
            passiveTrigger.Initialize(unit,elementSystem);
        }

        public void Initialize(UnitBase unit)
        {
            ((IComponent)this).OnInitialize(unit);
        }

        public void Birth()
        {
            ((IComponent)this).OnBirth();
        }

        public void Update()
        {
            ((IComponent) this).OnUpdate();
        }
        
        public void Dispose()
        {
            ((IClass)this).OnReset();
        }
        
        void IComponent.OnUpdate()
        {
            CheckIsAttackInCd();
            foreach (var item in skills.Values)
            {
                item.Update();
            }
            /*if (unit.Data.team == 0 && PveManager.Instance.isInRpg)
            {
                var cd = unit.Data.GetSkillCD();
                if (cd != lastCd)
                {
                    ResidentHandler.Inst.GetFunction("pveManager.UpdateHeroSKillCd").Action(unit.Data.id,cd);
                }
                lastCd = cd;
            }*/

            UpdateIsHeroCanSkill();
            /*if (unit.Data.id == 0 && isFocus && unit.Data.lockTarget == null)
            {
                PveManager.Instance.EndFocusBattle();
            }*/
            if (startReloadTime != 0)
            {
                if (TimeManager.logicTime - startReloadTime >= unit.Data.reloadTime)
                {
                    unit.Data.attackState = 0;
                    unit.Data.isReloading = false;
                }

                if (!unit.Data.isReloading)
                {
                    startReloadTime = 0;
                    RefreshLeftAmmo();
                }
                /*else if (unit.Data.isManualMoving && unit.Data.lockTarget != null && !unit.Data.lockTarget.Data.isDead)
                {
                    unit.Data.targetForward = unit.Data.lockTarget.Data.position - unit.Data.lockTarget.
                }*/
                
            }

            CheckPassiveSkillChange();
            CheckPassiveSkill();
            elementSystem.Update();
        }

        private bool isCanSkill;
        private void UpdateIsHeroCanSkill()
        {
            var isCanSkill = !unit.Data.IsInControl();
            if (isCanSkill != this.isCanSkill)
            {
                ResidentHandler.Inst.GetFunction("pveManager.SetHeroCanSkill").Action(unit.Data.heroId,isCanSkill);
            }
            this.isCanSkill = isCanSkill;
        }

        private void CheckPassiveSkillChange()
        {
            foreach (var item in addPassiveSkillList)
            {
                int skillId = item.Key;
                int level = item.Value;
                if (!skills.ContainsKey(skillId))
                {
                    var config = PveUtils.GetSkillConfig(skillId);
                    SkillBase skill = null;
                    if (config.type == 2)
                    {
                        skill = ClassManager.Get<SkillAuto>();
                    }
                    else if (config.type == 6)
                    {
                        skill = ClassManager.Get<SkillPassive>();
                    }

                    if (skill != null)
                    {
                        unit.Data.skillList.Add(skillId);
                        skill.Initialize(unit,skillId,config);
                        skill.skillType = 2;
                        skill.level = level;
                        skills.Add(skillId,skill);
                        passiveTrigger.AddSkillPassive(skillId,skill);
                    }
                }
            }
            addPassiveSkillList.Clear();
            
        }
        
        private void CheckPassiveSkill()
        {
            if (unit.Data.isDead)
            {
                return;
            }
            
            passiveTrigger.Update();
            if (passiveTrigger.IsPassiveSkillReady())
            {
                if (currentSkill != null && currentSkill.skillType == 0)
                {
                    currentSkill.ForceStop();
                }

                if (!unit.Data.isReloading && !unit.Data.IsInSkill() && !unit.Data.IsInAttack() && unit.Data.lockTarget != null && (unit.Data.IsAttackInRange() || unit.Data.isManualMoving))
                {
                    currentSkill = passiveTrigger.CastSkill();
                }
            }

        }
        
        void IComponent.OnBirth()
        {
            unit.Data.isDisarm = false;
            unit.Data.isSilent = false;
            unit.Data.hasJoinBattle = unit.Data.team == 0 || PveManager.Instance.isInPve;
        }

        void IComponent.OnDead()
        {
            foreach (var item in skills.Values)
            {
                if (!(item is SkillPassive))
                {
                    item.ForceStop();
                }
                
            }

            elementSystem?.OnDead();
            unit.Data.SetIsInAttack(false);
            //LuaManager.mainState.GetFunction("pveManager.SetIsHeroDead").Call(unit.Data.id,true);
        }

    
        
        void ITransmit.OnTransmit(ETransmitType type, BaseTransmitArg arg)
        {
            if (type == ETransmitType.AutoSearch)
            {
                //currentSkill?.Stop();
            }
            else if (type == ETransmitType.Attack)
            {
                /*if (unit.Data.isManualMoving && unit.Data.moveState == 2)
                {
                    return;
                }*/
                if (!unit.Data.hasReachAttackPosition)
                {
                    return;
                }
                

                if (PveGlobalVlues.HitAndRun == 1 && unit.Data.team == 0 && unit.Data.attackPosition != Vector3.zero &&
                    unit.Data.attackPosition != unit.Data.position)
                {
                    return;
                }
                
                if (unit.Data.isGoingToHidePoint)
                {
                    return;
                }
                if (unit.Data.IsInSkill() || unit.Data.IsInAttack() || !unit.Data.IsCanAttack())
                {
                    return;
                }
                if (unit.Data.isReloading)
                {
                    return;
                }

                if (unit.Data.isInAction)
                {
                    return;
                }

                if (CheckIsAttackInCd())
                {
                    return;
                }
                
                unit.Transmit(ETransmitType.BeforeAttack);
                //这时候进行攻击前判定，如果触发被动技能则不会普攻

                if (passiveTrigger.IsPassiveSkillReady())
                {
                    return;
                }

                
                if (unit.Data.isHiding)
                {
                    if (unit.Data.attackPosition == Vector3.zero)
                    {
                        return;
                    }
                    if (squatAttack != null)
                    {
                        unit.Data.SetIsInAttack(true);
                        var targetPosition = unit.Data.position + unit.Data.manualForward;
                        if (unit.Data.lockTarget != null)
                        {
                            targetPosition = unit.Data.lockTarget.Data.position;
                        }
                        unit.Data.SetTargetForward(targetPosition - unit.Data.position);
                        squatAttack.Play(targetPosition ,unit.Data.targetForward);
                        currentSkill = squatAttack;
                        //CalculateAttackCd();
                        return;
                    }
                }
                
                if (!unit.Data.isMoveAttacking)
                {
                    if (moveAttack != null && (unit.Data.manualForward != Vector3.zero||unit.Data.moveState == 1))
                    {
                        if (unit.Data.lockTarget != null && unit.Data.IsAttackInRange())
                        {
                            unit.Data.needNextShoot = true;
                            if (unit.Data.manualForward.sqrMagnitude <= 0.01f)
                            {
                                unit.Data.moveSpeed = 0;
                            }
                        }
                        if (!moveAttack.IsFinishCast())
                        {
                            return;
                        }
                        var targetPosition = unit.Data.position + unit.Data.manualForward;
                        if (unit.Data.lockTarget != null)
                        {
                            targetPosition = unit.Data.lockTarget.Data.position;
                        }
                        unit.Data.SetTargetForward(targetPosition - unit.Data.position);
                        moveAttack.Play(targetPosition ,unit.Data.targetForward);
                        currentSkill = moveAttack;
                        //CalculateAttackCd();
                        return;
                    }
                    bool hasAmmo = CheckHasAmmo();
                    /*if (!hasAmmo)
                    {
                        
                    }
                    else*/
                    {
                        unit.Data.SetTargetForward(unit.Data.lockTarget.Data.position - unit.Data.position);
                        //unit.Data.SetIsCanMove(false);
                        unit.Data.SetIsInAttack(true);
                        if (unit.Data.IsCanAttack())
                        {
                            if (unit.Data.id == 0 && !PveManager.Instance.isInRpg)
                            {
                                //PveManager.Instance.FocusBattle(unit.Data.lockTarget);
                                //isFocus = true;
                            }
                            if (unit.Data.team == 0)
                            {
                                unit.Data.attackPosition = Vector3.zero;
                            }
                            SkillBase skill;
                            int id = normalAttackId;
                            if (!unit.Data.isSilent)//被沉默了无法释放自动技能
                            {
                                
                            }

                            if (id == normalAttackId)
                            {
                                id = rpgNormalAttackList[currentNormalAttackIndex];
                                currentNormalAttackIndex++;
                                if (currentNormalAttackIndex >= rpgNormalAttackList.Count)
                                {
                                    currentNormalAttackIndex = 0;
                                }
                            }
                            if (skills.TryGetValue(id, out skill))
                            {
                                /*if (id != normalAttackId)
                                {
                                    PveFlyTextManager.Instance.ShowFlyText(skill.config.name,unit.Data.position + new Vector3(0,1f,0));
                                }
                                */
                                
                                skill.Play(unit.Data.lockTarget.Data.position ,unit.Data.targetForward);
                                currentSkill = skill;
                                //CalculateAttackCd();
                            }
                        }
                        else//无法攻击
                        {
                            unit.Play("Idle");
                        }
                    }
                }
            }
            else if (type == ETransmitType.Skill)
            {
                unit.Data.aimTransform = null;
                unit.Transmit(ETransmitType.CancelAim);
                //unit.Transmit(ETransmitType.SquatUp);
                currentSkill?.ForceStop();
               
                unit.Data.lastSkillTime = TimeManager.logicTime;
                SkillTransmitArg skillArg = arg as SkillTransmitArg;
                SkillBase skill;
                int skillId = skillArg.skillId;
                int percent = Random.Range(0, 100);
                for (int i = 0; i < subSkills.Count; i++)
                {
                    if (percent <= subSkills[i].x)
                    {
                        skillId = (int)subSkills[i].y;
                        //Debug.LogError((subSkills.Count - i + 1) + "重施法");
                        break;
                    }
                }
                if (skills.TryGetValue(skillId, out skill))
                {
                    //PveFlyTextManager.Instance.ShowFlyText(skill.config.name,unit.Data.position + new Vector3(0,1f,0));
                    unit.Data.SetIsInSkill(true);
                    skill.globalSkillIndex = skillArg.skillIndex;
                    skill.Play(skillArg.targetPosition,skillArg.targetForward,skillArg.targetUnits); //(skillArg.targetForward);
                    currentSkill = skill;
                }
            }

            else if (type == ETransmitType.AttackEnd)
            {
                if (unit.Data.searchChangeType == 1 && unit.Data.attractAttackTarget == null)
                {
                    unit.Data.SetLockTarget(null);
                    unit.Transmit(ETransmitType.AutoSearch);
                }

                CalculateAttackCd();
            }
            else if (type == ETransmitType.Kill)
            {
                unit.Data.killNum++;
                if (unit.Data.killNum >= 2)
                {
                    PveFlyTextManager.Instance.ShowFlyTextKill(unit.Data.killNum,unit.Data.GetHudPosition() + new Vector3(0,0.5f + unit.Data.hudHeight,0),unit.Data.id);
                }
                
            }
            else if (type == ETransmitType.AddControl)
            {
                //currentSkill?.Stop();
                //attackCd = 0;
            }
            else if (type == ETransmitType.RigidBreak)
            {
                /*var addControlArg = arg as AddControlArg;
                if (currentSkill == null)
                {
                    if (addControlArg.rigidBreak > 5)
                    {
                        unit.Transmit(ETransmitType.AddControl,addControlArg);
                    }
                }
                else
                {
                    if (currentSkill.config.rigid_intensity < addControlArg.rigidBreak)
                    {
                        unit.Transmit(ETransmitType.AddControl,addControlArg);
                    }
                }*/
            }
            else if (type == ETransmitType.RpgToNext)
            {
                currentSkill?.Stop();
            }
            else if (type == ETransmitType.AutoUseSkill)
            {
                /*if (unit.Data.lockTarget == null)
                {
                    return;
                }*/
                
                currentSkill?.ForceStop();

                if (unit.Data.team == 0)
                {
                    if (PveGlobalVlues.UseHeroMp)
                    {
                        PveCardManager.Instance.OnAutoCastCardUseMp(unit.Data.id);
                    }
                    else
                    {
                        PveCardManager.Instance.OnAutoCastCard();
                    }
                }
                else if (unit.Data.team == 2)
                {
                    if (PveGlobalVlues.UseHeroMp)
                    {
                        unit.SetMpChange(-unit.Data.mpCost);
                    }
                    else
                    {
                         UnitManager.Instance.enemyEnergy -= unit.Data.rpgSkillCost;
                    }
                   
                }

                unit.Data.hasAutoUsedSkill = true;
                unit.Data.lastSkillTime = TimeManager.logicTime;
                SkillBase skill;
                if (skills.TryGetValue(initiativeSkillId, out skill))
                {
                    //PveFlyTextManager.Instance.ShowFlyText(skill.config.name,unit.Data.position + new Vector3(0,1f,0));
                    unit.Data.SetIsInSkill(true);
                    if (arg is AutoUseSkillArg aarg)
                    {
                        skill.globalSkillIndex = aarg.skillIndex;
                        skill.Play(aarg.targetPosition,aarg.targetForward,aarg.targetList,true);
                    }
                    else
                    {
                        skill.PlayAuto();
                    }
                    currentSkill = skill;
                }
            }
            else if (type == ETransmitType.StageToNext)
            {
                if (unit.Data.team == 0)
                {
                    unit.Data.CurrentHp = unit.Data.TotalHp;
                    unit.Data.attackRange = unit.Data.pveAttackRange;
                    unit.Transmit(ETransmitType.UpdateHp);
                }
            }
            else if (type == ETransmitType.RPGStart)
            {
                unit.Data.aimTransform = null;
                unit.Transmit(ETransmitType.CancelAim);
                //ResidentHandler.Inst.GetFunction("pveManager.UpdateHeroHp").Action(unit.Data.heroId,unit.Data.CurrentHp,unit.Data.TotalHp);
            }
            else if (type == ETransmitType.RpgStageToNext)
            {
                if (unit.Data.team == 0)
                {
                    unit.Data.CurrentHp = unit.Data.TotalHp;
                    unit.Transmit(ETransmitType.UpdateHp);
                    unit.Transmit(ETransmitType.HideHud);
                }
            }
            else if (type == ETransmitType.Move)
            {
                if (unit.Data.moveState == 1)
                {
                    return;
                }

                if (unit.Data.aimTransform != null)
                {
                    unit.Data.aimTransform = null;
                    unit.Transmit(ETransmitType.CancelAim);
                }
                //currentSkill?.Stop();
            }
            else if (type == ETransmitType.SwitchToRpg)
            {
                unit.Data.CurrentHp = unit.Data.TotalHp;
                unit.SetHpChange(0);
                unit.SetMpChange(0);
            }
            else if (type == ETransmitType.ToRPG)
            {
                unit.Data.damageRatio = unit.Data.team == 0 ? 1f : 1f;
                unit.Data.attackRange = unit.Data.rpgAttackRange;
                
                /*if (unit.Data.team == 2)
                {
                    unit.Data.attackRange *= Random.Range(0.8f, 1.1f);
                }*/
                if (!unit.Data.hasInitedRpg)
                {
                    InitRpgSkills();
                    unit.Transmit(ETransmitType.UpdateHp);
                }
                unit.Data.hasInitedRpg = true;
            }
            else if (type == ETransmitType.ToPve)
            {
                unit.Data.damageRatio = 1f;
                unit.Data.attackRange = unit.Data.pveAttackRange;
                if (unit.Data.team == 2)
                {
                    unit.Data.damageRatio = 1;
                }
                InitRpgSkills();
                unit.Data.hasInitedRpg = true;
            }
            else if (type == ETransmitType.StageStart)
            {
                unit.Transmit(ETransmitType.UpdateHp);
            }
            else if (type == ETransmitType.HitOthers)
            {
                
            }
            else if (type == ETransmitType.BeHitByOthers)
            {
               
            }
            else if (type == ETransmitType.DestroyBullet)
            {
                foreach (var item in skills)
                {
                    item.Value.DestroyBullets();
                }
            }
            else if (type == ETransmitType.AddElement)
            {
                //if (!unit.Data.isDead)
                {
                    var elementArg = arg as AddElementArg;
                    //判断是否是硬直
                    bool abort = false;
                    /*if (elementArg.elementConfig.buff_type == 12)
                    {
                        abort = true;
                        if (currentSkill == null)
                        {
                            if (elementArg.rigidBreak > 5)
                            {
                                abort = false;
                            }
                        }
                        else
                        {
                            if (currentSkill.config.rigid_intensity * unit.Data.rigidRatio < elementArg.rigidBreak)
                            {
                                abort = false;
                            }
                        }
                    }*/

                    if (!abort)
                    {
                        elementSystem.AddElement(elementArg.id, elementArg.target, elementArg.source,
                            elementArg.elementConfig, elementArg.bulletPosition, elementArg.isCrit,
                            elementArg.rigidBreak, elementArg.sourceSkill,elementArg.isSkillAdditive);
                    }
                }
            }
            else if (type == ETransmitType.AddElementSuccess)
            {
                elementSystem.CheckTrigger((arg as AddElementSuccessArg).element);
            }
            else if (type == ETransmitType.RemoveElement)
            {
                var elementArg = arg as RemoveElementArg;
                elementSystem.RemoveElement(elementArg.removeType);
            }
            else if (type == ETransmitType.OnSkillEnd)
            {
                var skill = (arg as SkillEndArg).skill;
                elementSystem.OnSkillEnd(skill);
            }
            else if (type == ETransmitType.StopSkill)
            {
                currentSkill?.ForceStop();
            }
            else if (type == ETransmitType.ManualMove)
            {
                if (currentSkill != null && !(currentSkill is SkillInitiative) && !(currentSkill is SkillShootMove))
                {
                    currentSkill.Stop();
                    currentSkill = null;
                }
                //unit.Data.SetLockTarget(null);
            }
            else if (type == ETransmitType.Disarm)
            {
                /*if (currentSkill is NormalAttack)
                {
                    currentSkill.Stop();
                }*/
            }
            else if (type == ETransmitType.RemoveDisarm)
            {
                unit.Data.SetIsInAttack(false);
            }
            else if (type == ETransmitType.Silent)
            {
                if (currentSkill is SkillInitiative)
                {
                    currentSkill.ForceStop();
                }
            }
            else if (type == ETransmitType.RemoveSilent)
            {
                unit.Data.SetIsInSkill(false);
            }
            else if (type == ETransmitType.AddOrder)
            {
                var order = ((AddOrderTransmitArg) arg).order;
                if (order.type != UnitOrder.EOrderType.Skill)
                {
                    currentSkill?.ForceStop();
                }
            }
            else if (type == ETransmitType.Reload)
            {
                if (startReloadTime != 0)
                {
                }
                else
                {
                    unit.Play("Reload");
                    unit.Data.attackState = 1;
                    //PveFlyTextManager.Instance.ShowFlyText("Reload",unit.Data.position + new Vector3(0,1f,0));
                    unit.Transmit(ETransmitType.ReloadStart);
                    startReloadTime = TimeManager.logicTime;
                    unit.Data.isReloading = true;
                    if (unit.Data.switchWeaponId != 0)
                    {
                        unit.Data.switchWeaponId = 0;
                        SwitchWeapon(unit.Data.switchWeaponId);
                    }
                }
            }
            else if (type == ETransmitType.SwitchWeapon)
            {
                var switchWeaponArg = arg as SwitchWeaponArg;
                unit.Data.switchWeaponId = switchWeaponArg.weaponId;
                SwitchWeapon(switchWeaponArg.weaponId);
            }
            else if (type == ETransmitType.AddCardSkill)
            {
                var addWeaponSkillArg = arg as AddCardSkillArg;
                var skillId = addWeaponSkillArg.skillId;
                if (!skills.ContainsKey(skillId))
                {
                    unit.Data.skillList.Add(skillId);
                    var config = PveUtils.GetSkillConfig(skillId);
                    var skill = ClassManager.Get<SkillInitiative>();
                    skill.Initialize(unit,skillId,config);
                    skills.Add(skillId,skill);
                }
                
            }
            else if (type == ETransmitType.ChangePassiveSkill)
            {
                
                /*var changePassiveSkillArg = arg as ChangePassiveSkill;
                if (changePassiveSkillArg.state == 0)
                {
                    var skillId = changePassiveSkillArg.skillId;
                    addPassiveSkillList.Add(skillId);
                }
                else if (changePassiveSkillArg.state == 1)
                {
                    //passiveTrigger.RemoveSkillPassive(changePassiveSkillArg.skillId);
                    removePassiveSkillList.Add(changePassiveSkillArg.skillId);
                }*/
                var changePassiveSkillArg = arg as ChangePassiveSkill;
                int skillId = changePassiveSkillArg.skillId;
                if (changePassiveSkillArg.state == 0)
                {
                    addPassiveSkillList.Add(skillId,changePassiveSkillArg.skillLevel);
                    
                }
            }
            else if (type == ETransmitType.ChangeExtraElement)
            {
                var sArg = arg as ExtraElementArg;
                if (skills.TryGetValue(sArg.skillId, out var skill))
                {
                    skill.ChangeExtraElement(sArg.bulletId, sArg.elementId, sArg.action);
                }
            }
            else if (type == ETransmitType.ChangeBullet)
            {
                var sArg = arg as ChangeBulletArg;
                if (sArg.changeSkillType == 1)
                {
                    foreach (var item in skills.Values)
                    {
                        if (item.skillType == 0)
                        {
                            item.ChangeSpecificBullet(sArg.changeBulletOldId,sArg.changeBulletNewId,sArg.action);
                            item.level = sArg.changeSkillLevel;
                        }
                    }
                }
            }
            else if (type == ETransmitType.ChangeElement)
            {
                var sArg = arg as ChangeElementArg;
                if (skills.TryGetValue(sArg.skillId, out var skill))
                {
                    skill.ChangeSpecificElement(sArg.bulletId, sArg.oldElementId, sArg.newElementId);
                }
            }
            else if (type == ETransmitType.StageEnd)
            {
                foreach (var item in skills.Values)
                {
                    item.Clear();
                }
            }
            else if (type == ETransmitType.LogicPause)
            {
                /*if (unit.Data.isDead)
                {
                    return;
                }*/
                currentSkill?.ForceStop();
                foreach (var item in skills.Values)
                {
                    item.RemoveAllBullets();
                }
                //elementSystem.Pause();
            }
            else if (type == ETransmitType.Pause)
            {
                foreach (var item in skills.Values)
                {
                    item.Pause();
                }
                elementSystem.Pause();
            }
            else if (type == ETransmitType.Resume)
            {
                foreach (var item in skills.Values)
                {
                    item.Resume();
                }
                elementSystem.Resume();
            }
            else if (type == ETransmitType.RecoverSkillInitiative)
            {
                if (!unit.Data.isDead && currentSkill != null && currentSkill.skillType == 1)
                {
                    currentSkill.StartRecoverFromExternal();
                }
            }
            else if (type == ETransmitType.RecoverSkillAuto)
            {
                if (!unit.Data.isDead && currentSkill != null && currentSkill.skillType == 2)
                {
                    currentSkill.StartRecoverFromExternal();
                }
            }
            passiveTrigger?.Transmit(type, arg);
        }

        private void CalculateAttackCd()
        {
            attackCdStartTime = TimeManager.logicTime;
            attackCd = 0;//currentSkill.config.attack_cast_time * unit.Data.shootTurns;
            if (unit.Data.shootInterval.Count > 1)
            {
                attackCd += Random.Range(unit.Data.shootInterval[0],unit.Data.shootInterval[1]);
            }
            else
            {
                attackCd += Random.Range(0, 2);
            }
            attackCd /= unit.Data.attackSpeedRatio;
        }
        
        private void SwitchWeapon(int weaponId)
        {
            if (weaponId == 0)
            {
                unit.Data.attackRange = unit.Data.rpgAttackRange;
                unit.Data.leftAmmoCount = unit.Data.ammoCount;
                unit.Data.weaponAttackSpeed = 1;
            }
            else
            {
                var config = PveUtils.GetWeaponConfig(weaponId);
                if (config != null)
                {
                    unit.Data.attackRange = unit.Data.rpgAttackRange * config.range;
                    unit.Data.leftAmmoCount = config.ammo;
                    unit.Data.weaponAttackSpeed = config.speed;
                }
            }
        }
        

        private BattleUnit lastLockTarget;
        private bool CheckIsAttackInCd()
        {
            if (unit.Data.isReloading || unit.Data.IsInSkill() || unit.Data.IsInAttack() || !unit.Data.IsInitiative() || unit.Data.isMoveAttacking)
            {
                return false;
            }
            
            bool isInCd = false;
            if (attackCdStartTime > 0)
            {
                if (TimeManager.logicTime - attackCdStartTime < attackCd)
                {
                    isInCd = true;
                    if (unit.Data.moveState == 0)
                    {
                        unit.Play("Idle");
                    }

                    if (unit.Data.lockTarget != null)
                    {
                        unit.Data.SetTargetForward(unit.Data.lockTarget.Data.position - unit.Data.position);
                    }
                    //unit.Data.SetIsInAttack(true);
                }
                else
                {
                    isInCd = false;
                    attackCdStartTime = 0;
                    unit.Data.SetIsInAttack(false);
                }
            }
            return isInCd;
        }

        private void AddMp(int value)
        {
        }

        private bool CheckHasAmmo()
        {
            if (unit.Data.leftAmmoCount == -1)
            {
                return true;
            }

            return unit.Data.leftAmmoCount > 0;
        }

        private void InitSkills()
        {
            skills.Clear();
            for (int i = 0; i < unit.Data.skillList.Count; i++)
            {
                var config = PveUtils.GetSkillConfig(unit.Data.skillList[i]);
                int level = 1;
                SkillBase skill = null;
                if (config.type == 1)
                {
                    skill = ClassManager.Get<SkillInitiative>();
                    level = unit.Data.rpgSkillInitiativeLevel;
                }
                else if (config.type == 2)
                {
                    skill = ClassManager.Get<SkillAuto>();
                    skill.Initialize(unit,unit.Data.skillList[i],config);
                    passiveTrigger.AddSkillPassive(unit.Data.skillList[i],skill);
                    level = unit.Data.GetPassiveSkillLevel(config.id);
                }
                else if (config.type == 3)
                {
                    skill = ClassManager.Get<SkillShootBase>();
                }
                else if (config.type == 4)
                {
                    skill = ClassManager.Get<SkillShootMove>();
                    moveAttack = (SkillShootMove) skill;
                }
                else if (config.type == 5)
                {
                    skill = ClassManager.Get<SkillMelee>();
                }
                else if (config.type == 6)
                {
                    skill = ClassManager.Get<SkillPassive>();
                    skill.Initialize(unit,unit.Data.skillList[i],config);
                    passiveTrigger.AddSkillPassive(unit.Data.skillList[i],skill);
                    level = unit.Data.GetPassiveSkillLevel(config.id);
                }

                if (unit.Data.skillList[i] == normalSquatAttackId && skill != null)
                {
                    squatAttack = (SkillShootBase)skill;
                }
                
                if (skill == null)
                {
                    continue;
                }
                skill.Initialize(unit,unit.Data.skillList[i],config);
                skill.level = level;
                if (unit.Data.skillList[i] == normalAttackId || unit.Data.skillList[i] == normalSquatAttackId || skill is SkillShootMove)
                {
                    if (unit.Data.team == 0 && PveGlobalVlues.PlayerNormalAttackCauseHit)
                    {
                        //给我方普攻添加硬直
                        for (int j = 0; j < skill.config.bullets.Count; j++)
                        {
                            skill.ChangeExtraElement((int)skill.config.bullets[j].y, PveGlobalVlues.hitElementId,0);
                        }
                    }
                    skill.skillType = 0;
                }
                else if (skill is SkillInitiative)
                {
                    if (unit.Data.team == 0 && PveGlobalVlues.PlayerSkillCauseHit)
                    {
                        //给我方技能添加硬直
                        for (int j = 0; j < skill.config.bullets.Count; j++)
                        {
                            skill.ChangeExtraElement((int)skill.config.bullets[j].y, PveGlobalVlues.hitElementId,0);
                        }
                    }
                    skill.skillType = 1;
                }
                else
                {
                    skill.skillType = 2;
                }
                skills.Add(unit.Data.skillList[i],skill);
            }

            if (unit.Data.bornElements.Count > 0)
            {
                bornSkill = ClassManager.Get<SkillBase>();
                bornSkill.level = 1;
                for (int i = 0; i < unit.Data.bornElements.Count; i++)
                {
                    int elementId = unit.Data.bornElements[i];
                    var elementConfig = PveUtils.GetSkillElementConfig(elementId);
                    AddElementArg arg = ClassManager.Get<AddElementArg>();
                    arg.id = elementId;
                    arg.source = unit;
                    arg.target = unit;
                    arg.elementConfig = elementConfig;
                    arg.isCrit = false;
                    arg.sourceSkill = bornSkill;
                    unit.Transmit(ETransmitType.AddElement,arg);
                    ClassManager.Free(arg);
                }
            }
        }

        private void InitRpgSkills()
        {
            currentNormalAttackIndex = 0;
            unit.Data.skillList.Clear();
            normalAttackId = unit.Data.rpgNormalAttackId;
            rpgNormalAttackList.Clear();
            rpgNormalAttackList.Add(unit.Data.rpgNormalAttackId);
            
            if (unit.Data.rpgPassiveSkillIds != null)
            {
                Dictionary<int,int> newPassiveSkills = new Dictionary<int, int>();
                foreach(var item in unit.Data.rpgPassiveSkillIds.Keys)
                {
                    var config = PveUtils.GetSkillConfig(item );
                    if (config.type == 7) //组合类技能
                    {
                        var level = unit.Data.GetPassiveSkillLevel(item);
                        for (int j = 0; j < config.child_skills.Count; j++)
                        {
                            int newPassiveId = config.child_skills[j];
                            unit.Data.skillList.Add(newPassiveId);
                            newPassiveSkills[newPassiveId] = level;
                            //unit.Data.rpgPassiveSkillIds[newPassiveId] = level;
                        }
                    }
                    else
                    {
                         unit.Data.skillList.Add(item);
                    }
                }
                foreach (var item in newPassiveSkills)
                {
                    unit.Data.rpgPassiveSkillIds[item.Key] = item.Value;
                }
            }

            
            int skillId = unit.Data.rpgSkillId;
            unit.Data.skillList.Add(normalAttackId);
            if (skillId != 0)
            {
                unit.Data.skillList.Add(skillId);
                initiativeSkillId = skillId;
            }

            normalSquatAttackId = unit.Data.rpgNormalSquatAttackId;
            unit.Data.isCanSquat = normalSquatAttackId != 0;
            if (normalSquatAttackId != 0)
            {
                unit.Data.skillList.Add(normalSquatAttackId);
            }
            

            if (unit.Data.rpgMoveAttackId != 0)
            {
                unit.Data.skillList.Add(unit.Data.rpgMoveAttackId);
            }

            var replaceSkills = new List<int>();
            for (int i = 0; i < unit.Data.skillList.Count; i++)
            {
                var config = PveUtils.GetSkillConfig(unit.Data.skillList[i]);
                if (config != null && config.replace_skills != null)
                {
                    for (int j = 0; j < config.replace_skills.Count; j++)
                    {
                        replaceSkills.Add(config.replace_skills[j].x);
                    }
                }
            }

            for (int i = 0; i < replaceSkills.Count; i++)
            {
                int replaceSkillId = replaceSkills[i];
                if (!unit.Data.skillList.Contains(replaceSkillId))
                {
                    unit.Data.skillList.Add(replaceSkills[i]);
                }
            }

            /*for (int i = 0; i < unit.Data.rpgSubSkills.Count; i++)
            {
                unit.Data.skillList.Add((int)unit.Data.config.rpgSubSkills[i].y);
            }
            subSkills = unit.Data.config.rpgSubSkills;*/
            subSkills = new List<Vector3>();
            /*if (unit.Data.id == 0)
            {
                unit.Data.skillList.Add((int)ESkillId.basicSkill1);
                unit.Data.skillList.Add((int)ESkillId.basicSkill2);
                unit.Data.skillList.Add((int)ESkillId.basicSkill3);
                unit.Data.skillList.Add((int)ESkillId.basicSkill4);
                unit.Data.skillList.Add((int)ESkillId.basicSkill5);
            }

            var weaponList = PveCardManager.Instance.GetWeaponSkillByWeaponType(unit.Data.weaponType);
            for (int i = 0; i < weaponList.Count; i++)
            {
                unit.Data.skillList.Add(weaponList[i]);
            }*/
            
            RefreshLeftAmmo();
            InitSkills();
            
        }

        private int GetReplaceSkillId(PveSkillConfig config)
        {
            int skillId = config.id;
            if (config.replace_skills != null)
            {
                var random = Random.Range(0, 100);
                for (int i = 0; i < config.replace_skills.Count; i++)
                {
                    if (random > config.replace_skills[i].y)
                    {
                        skillId = config.replace_skills[i].x;
                        break;
                    }
                }
            }
            return skillId;
        }
        
        private void RefreshLeftAmmo()
        {
            if (unit.Data.totalAmmoCount == 0)
            {
                unit.Data.leftAmmoCount = -1;
            }
            else
            {
                unit.Data.leftAmmoCount = unit.Data.totalAmmoCount;
            }
            unit.Transmit(ETransmitType.ReloadEnd);
        }
        
    }
}
